//
//  Model.cpp
//  OpenGL StarShip
//
//  Created by Tariqul Islam on 6/1/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#include "cmath"

#include "SDL/SDL.h"
#include "SDL/SDL_opengl.h"

#include <iostream>
using namespace std;

#include "headers/SpaceShip.h"


SpaceShip::SpaceShip(){
    body_color[0] = 0.5f;
    body_color[1] = 0.5f;
    body_color[2] = 0.5f;
}

void draw_wing(SpaceShip *model){
    GLfloat redEmissiveMaterial[] = {1.0f,0.0f,0.0f,10.0f};
    glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, redEmissiveMaterial);
    glColor3f(0.8f, 0.4f, 0.0f);
    //glutSolidSphere(2.5f, 30, 30);
    GLfloat blankMaterial[] = {0.0f,0.0f,0.0f,0.0f};
    glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION,blankMaterial);
    
    GLUquadric *quadric = gluNewQuadric(); 
    
    gluQuadricDrawStyle(quadric, GLU_FILL);
    gluQuadricNormals(quadric, GLU_SMOOTH);
    
    glColor3fv(model->body_color);
    gluCylinder(quadric, 3.2, 3.3, 3, 100, 1); 
    glPushMatrix();{
        glTranslatef(0.0f, 0.0f, 3.0f);
        gluCylinder(quadric, 3.3f, 3.0, 0.3f, 30, 1);
    }glPopMatrix();
    gluQuadricOrientation(quadric, GLU_INSIDE);
    gluDisk(quadric, 1.0f, 3.2f, 30.0f, 3.0f);
    gluQuadricOrientation(quadric, GLU_OUTSIDE);
    gluCylinder(quadric, 3, 2, 50, 100, 1); 
    glPushMatrix();{
         glColor3f(0.1f, 0.1f, 0.15f);
        glTranslatef(0.0f, 0.0f, 50.0f);
        gluDisk(quadric, 0.0f, 2.0f, 30.0f, 3.0f);
    }glPopMatrix();
    gluDeleteQuadric(quadric);
    
    //fuel ejector
    glColor3f(0.1f, 0.1f, 0.1f);
    glPushMatrix();{
        glTranslatef( 0.0f, 0.0f, 50.0f);
        glScalef(1.0f, 1.0f, 0.5f);
        GLdouble eqn1[] = {0.0,-1.0,-1.0,3.0};
        glClipPlane( GL_CLIP_PLANE0, eqn1 );
        glEnable(GL_CLIP_PLANE0);
        gluCylinder(quadric, 2.0f, 1.8f, 5.0, 30, 1);
        glDisable(GL_CLIP_PLANE0);
        
        
    }glPopMatrix();    
    
    //decoration around front
//    glColor3f(0.1f, 0.1f, 0.15f);
//    glPushMatrix();{
//        glTranslated(0.0f, 3.0f, 3.0f);
//        glScalef(0.3f, 0.1f, 0.9f);
//        glutSolidCube(6.0f);
//    }glPopMatrix();
//
//    glPushMatrix();{
//        glRotatef(60.0f, 0.0f, 0.0f, 1.0f);
//        glTranslated(0.0f, 3.0f, 3.0f);
//        glScalef(0.3f, 0.1f, 0.9f);
//        glutSolidCube(6.0f);
//    }glPopMatrix();
//
//    glPushMatrix();{
//        glRotatef(-60.0f, 0.0f, 0.0f, 1.0f);
//        glTranslated(0.0f, 3.0f, 3.0f);
//        glScalef(0.3f, 0.1f, 0.9f);
//        glutSolidCube(6.0f);
//    }glPopMatrix();
//
//    //decoration at back
//    glPushMatrix();{
//        glRotatef(-45.0f, 0.0f, 0.0f, 1.0f);
//        glTranslated(0.0f, -2.5f, 45.0f);
//        glScalef(0.1f, 0.3f, 0.9f);
//        glutSolidCube(6.0f);
//    }glPopMatrix();
//
//    glPushMatrix();{
//        glRotatef(45.0f, 0.0f, 0.0f, 1.0f);
//        glTranslated(0.0f, -2.5f, 45.0f);
//        glScalef(0.1f, 0.3f, 0.9f);
//        glutSolidCube(6.0f);
//    }glPopMatrix();
//
//    glColor3f(0.0f, 0.0f, 0.0f);
//    //side decoration
//    glPushMatrix();{
//        glRotatef(90.0f, 0.0f, 0.0f, 1.0f);
//        glTranslated(0.0f, -2.7f, 25.0f);
//        glScalef(0.1f, 0.01f, 0.9f);
//        glutSolidCube(20.0f);
//    }glPopMatrix();


}


void draw_body(SpaceShip *model){
    GLUquadric *quadric = gluNewQuadric();
    gluQuadricDrawStyle(quadric, GLU_FILL);
    gluQuadricNormals(quadric, GLU_SMOOTH);
    gluQuadricOrientation(quadric, GLU_OUTSIDE);
    
    


    
    const int CYLINDER_LENGTH = 6;
    float cylinder_length[CYLINDER_LENGTH] =       {3.0f, 7.0, 5.0f , 20.0f , 10.0f , 5.0f};
    float cylinder_radious[CYLINDER_LENGTH+1] = {5.5f ,6.0 ,  6.5f , 6.5f , 4.5f , 4.0f , 3.5f};
 
    //MAIN BODY
    glColor3fv(model->body_color);
    glPushMatrix();   
    for(int i = 0 ; i<CYLINDER_LENGTH ;i++){
        gluCylinder(quadric, cylinder_radious[i], cylinder_radious[i+1], cylinder_length[i], 50, 1);
        glTranslatef(0.0f, 0.0f, cylinder_length[i]);  
    }
    glPopMatrix();
    
    //front cover
    gluQuadricOrientation(quadric, GLU_INSIDE);
    gluDisk(quadric, 1.0f, cylinder_radious[0], 30.0f, 3.0f);
    gluQuadricOrientation(quadric, GLU_OUTSIDE);
    //back cover
    glPushMatrix();{
        glTranslatef(0.0f, 0.0f, 50);
        gluDisk(quadric, 0.0f, cylinder_radious[CYLINDER_LENGTH], 30.0f, 3.0f);        
    }glPopMatrix();
    

    

    

    
    
    //fuel ejector
    glColor3f(0.3f, 0.3f, 0.3f);
    glPushMatrix();{
        glTranslatef( 0.0f, 0.0f, 48.0f);
//        glScalef(1.0f, 1.0f, 0.5f);
        GLdouble eqn1[] = {0.0,-1.0,-1.0,5.0};
        glClipPlane( GL_CLIP_PLANE0, eqn1 );
        glEnable(GL_CLIP_PLANE0);
        gluCylinder(quadric, 3.5f, 3.0f, 10.0, 30, 1);
        glDisable(GL_CLIP_PLANE0);
    }glPopMatrix();    
    
    
    
    glColor3fv(model->body_color);
    //draw dish antena
    glPushMatrix();{
        // dish
        glPushMatrix();{
            glTranslatef( 0.0f, 0.0f, -4.0f);
            glScalef(1.0f, 1.0f, 0.5f);
            GLdouble eqn1[] = {0.0,0.0,1.0,0.0};
            glClipPlane( GL_CLIP_PLANE0, eqn1 );
            glEnable(GL_CLIP_PLANE0);
            gluQuadricOrientation(quadric, GLU_INSIDE);
            gluSphere(quadric, 5.0f, 30.0f, 30.0f);
            gluQuadricOrientation(quadric, GLU_OUTSIDE);
            gluSphere(quadric, 5.1f, 30.0f, 30.0f);
            glDisable(GL_CLIP_PLANE0);
        }glPopMatrix();
        //antena
        glColor3f(0.0f, 0.0f, 0.0f);
        glPushMatrix();{
            glTranslatef(0.0f, 0.0f, -10.0f);
            gluCylinder(quadric, 0.1f, 0.3f, 10, 100, 1);
            GLfloat redEmissiveMaterial[] = {1.0f,0.0f,0.0f,10.0f};
            glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, redEmissiveMaterial);
            glColor3f(0.8f, 0.4f, 0.0f);
            gluSphere(quadric, 0.5f, 30, 30);
            GLfloat blankMaterial[] = {0.0f,0.0f,0.0f,0.0f};
            glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION,blankMaterial);
        }glPopMatrix();
    }glPopMatrix();

    
    //Decoration behind dish antena
    glColor3f(0.6f,0.6f,0.6f);
    const int INNER_CYLINDER_DISP =3;
    float innier_cylinders_displacement[INNER_CYLINDER_DISP] = {-1.0f,-1.5f,-2.0f};
    glPushMatrix();
    for(int i = 0 ; i < 4; i++){
        glPushMatrix();
        glTranslatef(0.0f, 0.0f, innier_cylinders_displacement[i]);
        gluCylinder(quadric, cylinder_radious[0]-0.3-i, cylinder_radious[0]-i/5.0, cylinder_length[0], 50, 1);        
        glPopMatrix();
    }
    glPopMatrix();
    
    //decoration around front
//    glColor3f(0.1f, 0.1f, 0.3f);
//    glPushMatrix();{
//        glTranslated(5.2f, 0.0f, 2.0f);
//        glScalef(0.1f, 0.3f, 0.5f);
//        glutSolidCube(12.0f);
//    }glPopMatrix();
//    glPushMatrix();{
//        glTranslated(-5.2f, 0.0f, 2.0f);
//        glScalef(0.1f, 0.3f, 0.5f);
//        glutSolidCube(12.0f);
//    }glPopMatrix();
//    glPushMatrix();{
//        glTranslated(0.0f, 5.2f, 2.0f);
//        glScalef(0.3f, 0.1f, 0.5f);
//        glutSolidCube(12.0f);
//    }glPopMatrix();
//    glPushMatrix();{
//        glTranslated(0.0f, -5.2f, 2.0f);
//        glScalef(0.3f, 0.1f, 0.5f);
//        glutSolidCube(12.0f);
//    }glPopMatrix();

    
    
   // gluCylinder(quadric, 5, 5.5f, 10.0f, 100, 10);
    //glTranslatef(0.0f, 0.0f, 10.0f);
    //gluCylinder(quadric, 5.5f, 5.5f, 10.0f, 100, 10);

}


void draw_wing_handle(SpaceShip *model){
    GLUquadric *quadric = gluNewQuadric(); 
    
    gluQuadricDrawStyle(quadric, GLU_FILL);
    gluQuadricNormals(quadric, GLU_SMOOTH);
    gluQuadricOrientation(quadric, GLU_OUTSIDE);
    
    glColor3fv(model->body_color);
    glPushMatrix();{
        glRotatef(-90.0f, 0.0f, 1.0f, 0.0f);
        glTranslated(10.0f, 0.0f, 0.0f);
        glRotatef(45, 1.0f, 0.0f, 0.0f);
        glScalef(0.6f, 0.2f, 1.0f); 
        gluCylinder(quadric, 5.0f, 5.0f, 40.0f, 30.0f, 1.0f);
        glColor3f(0.0F, 0.0F, 0.0F);
//        glPushMatrix();{
//            glTranslated(0.0f, -3.0f, 35.0f);
//            glutSolidCube(5.0f);
//        }glPopMatrix();
//
//        glPushMatrix();{
//            glTranslated(0.0f, -3.0f, 26.66f);
//            glutSolidCube(5.0f);
//        }glPopMatrix();
//
//        glPushMatrix();{
//            glTranslated(0.0f, -3.0f, 18.33f);
//            glutSolidCube(5.0f);
//        }glPopMatrix();
//
//        glPushMatrix();{
//            glTranslated(0.0f, -3.0f, 10.0f);
//            glutSolidCube(5.0f);
//        }glPopMatrix();

    }glPopMatrix();
}


void draw_disk(SpaceShip *model){
    GLUquadric *quadric = gluNewQuadric(); 
    
    gluQuadricDrawStyle(quadric, GLU_FILL);
    gluQuadricNormals(quadric, GLU_SMOOTH);
    gluQuadricOrientation(quadric, GLU_OUTSIDE);

    const int CYLINDER_LENGTH = 11;
    float cylinder_length[CYLINDER_LENGTH] =       {1.0f, 0.8f,   0.6f ,  0.4f ,  2.0f ,     2.0f,   0.4f ,   0.4f ,  0.6f , 0.6f,  0.4};
    float cylinder_radious[CYLINDER_LENGTH+1] = {0.0f ,9.0 , 12.0f , 15.0f , 18.0f , 19.0f*1.5 , 30.0f,29.7f, 18.0f, 12.0f , 6.0f , 0.0f};
    
    //MAIN BODY
    
    glColor3fv(model->body_color);
    glPushMatrix();   
    glRotatef(90, 1.0f, 0.0f, 0.0f);
    for(int i = 0 ; i<CYLINDER_LENGTH ;i++){
        gluCylinder(quadric, cylinder_radious[i], cylinder_radious[i+1], cylinder_length[i], 50, 1);
        glTranslatef(0.0f, 0.0f, cylinder_length[i]);  
    }
    glPopMatrix();
    
    //simple scaled sphere to make the top and down side of the disk round
    glPushMatrix();{
        glTranslatef(0.0f, -5.0f, 0.0f);
        glScalef(1.0f, 0.4f, 1.0f);
        gluSphere(quadric, 14.0f, 50.0f, 50.0f);
    }glPopMatrix();
    
    
    //this is emmisive sphere at the top of disk
    GLfloat redEmissiveMaterial[] = {0.7f,0.4f,0.0f,10.0f};
    glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, redEmissiveMaterial);
    glColor3f(0.2f, 0.2f, 0.0f);
    glPushMatrix();{
        glTranslatef(0.0f, -9.0f, 0.0f);
        gluSphere(quadric, 3.0f, 50.0f, 50.0f);
    }glPopMatrix();   
    GLfloat blankMaterial[] = {0.0f,0.0f,0.0f,0.0f};
    glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION,blankMaterial);
   
}


void draw_disk_handle(SpaceShip *model){
    GLUquadric *quadric = gluNewQuadric(); 
    
    gluQuadricDrawStyle(quadric, GLU_FILL);
    gluQuadricNormals(quadric, GLU_SMOOTH);
    gluQuadricOrientation(quadric, GLU_OUTSIDE);
    
    glColor3fv(model->body_color);
    glPushMatrix();{
        glTranslated(0.0f, 0.0f, -12.0f);
        glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
        glScalef(0.2f, 0.8f, 1.0f); 
        float shear[] = { 
            1, 0, 0, 0, 
            0, 1, 0, 0,
            0, -0.8, 1, 0,
            0, 0, 0, 1 };
        glMultMatrixf(shear);
        gluCylinder(quadric, 8.0f, 6.0f, 25.0f, 30.0f, 1.0f);
    }glPopMatrix();
}

void SpaceShip::draw(){
    glPushMatrix();
    
    this->transform.update();
    
    //draw right wing
    glPushMatrix();{
        glRotatef(180, 1.0f, 0.0f, 0.0f);
        glTranslatef(-30.0f, -30.0f, 0.0f);
        draw_wing(this);
    }glPopMatrix();
    
    //draw left wing
    glPushMatrix();{
        glRotatef(180, 1.0f, 0.0f, 0.0f);
        glTranslatef(30.0f, -30.0f, 0.0f);
        glScalef(-1.0f, 1.0f, 1.0f);
        draw_wing(this);
    }glPopMatrix();
    
    
    //draw body
    glPushMatrix();{
        glRotatef(180, 1.0f, 0.0f, 0.0f);
        glTranslatef(0.0f, 0.0f, -25.0f);
        draw_body(this);                
    }glPopMatrix();

    //draw right wing handle
    glPushMatrix();{
        glRotatef(180, 1.0f, 0.0f, 0.0f);
        draw_wing_handle(this);
    }glPopMatrix();
    
    //draw left wing handle
    glPushMatrix();{
        glRotatef(180, 1.0f, 0.0f, 0.0f);
        glScalef(-1.0f, 1.0f, 1.0f);
        draw_wing_handle(this);
    }glPopMatrix();
    
    
    //draw the disk
    glPushMatrix();{
        glRotatef(180, 1.0f, 0.0f, 0.0f);
        glTranslatef(0.0f, -20.0f, -45.0f);
        glScalef(1.2f, 1.2f, 1.2f);
        draw_disk(this);
    }glPopMatrix();
    
    //draw disk handle
    glPushMatrix();{
        glRotatef(180, 1.0f, 0.0f, 0.0f);        
        draw_disk_handle(this);
    }glPopMatrix();


    glPopMatrix();
}

